package com.yuyou.fn.settlement.service.impl;

import com.github.wens.mybatisplus.examples.Example;
import com.yuyou.fn.common.exception.BusException;
import com.yuyou.fn.common.util.BeanUtils;
import com.yuyou.fn.common.util.TimeUtils;
import com.yuyou.fn.settlement.constant.Subjects;
import com.yuyou.fn.settlement.entity.ChangeRecord;
import com.yuyou.fn.settlement.entity.MainAccount;
import com.yuyou.fn.settlement.service.IChangeRecordService;
import com.yuyou.fn.settlement.service.IMainAccountService;
import com.yuyou.fn.settlement.service.ISettlementService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by wens on 2017/3/24.
 */
@Service
public class SettlementServiceImpl implements ISettlementService {


    @Resource
    private IMainAccountService mainAccountService ;

    @Resource
    private IChangeRecordService changeRecordService ;


    @Override
    public void bookFee(Long mainAccountId, Long relMainAccountId, BigDecimal amount, String remark ,String tags , Long trackingId) {
        book( mainAccountId ,amount ,0,remark , Subjects.COST ,relMainAccountId ,amount ,0 ,Subjects.REAL_INCOME  , remark, trackingId, tags );
    }


    @Override
    public void bookIncomeForCourse(Long mainAccountId, Long relMainAccountId, BigDecimal amount, String className ,Long  classId , Long regId ) {
        List<ChangeRecord> changeRecordList = book(mainAccountId, amount , 0 , "【" + className + "】收入", Subjects.FUTURE_INCOME, relMainAccountId, amount,0, "购买【" + className + "】", Subjects.COST, regId, "class:" + classId);
        decreaseBalance(relMainAccountId,amount);
        markBookToBalance(changeRecordList.get(1));
    }

    @Transactional
    @Override
    public void bookRefundForCourse(Long mainAccountId, Long relMainAccountId, BigDecimal amount, String className, Long classId, Long regId) {
        List<ChangeRecord> changeRecordList = book(mainAccountId, new BigDecimal(-amount.doubleValue()),0 , "【" + className + "】退款", Subjects.FUTURE_INCOME, relMainAccountId, amount,0 , "【" + className + "】退款" , Subjects.REAL_INCOME, regId, "class:" + classId);
        increaseBalance(relMainAccountId,amount);
        markBookToBalance(changeRecordList.get(1));
    }

    private void markBookToBalance(ChangeRecord changeRecord) {

        //changeRecord.setSettleStatus(1);
        ChangeRecord update = new ChangeRecord();
        update.setChangeRecordId(changeRecord.getChangeRecordId());
        update.setSettleStatus(1);
        changeRecordService.updateSelectiveById(update);

    }


    /**
     * zhi zhifu  * @param mainAccountId
     * @param amount
     * @param direction
     * @param remark
     * @param subject
     * @param relMainAccountId
     * @param relAmount
     * @param relDirection
     * @param relRemark
     * @param relSubject
     * @param trackingId
     * @param tags
     * @return
     */
    private List<ChangeRecord> book(Long mainAccountId , BigDecimal amount ,Integer direction , String remark, String subject , Long relMainAccountId  , BigDecimal relAmount ,Integer relDirection , String relRemark , String relSubject , Long trackingId, String tags) {

        List<MainAccount> mainAccountList = mainAccountService.findByIds(Arrays.asList(mainAccountId, relMainAccountId));
        Map<Long,MainAccount> mainAccountMap = BeanUtils.toMap(mainAccountList,"mainAccountId") ;

        Date now = TimeUtils.now();
        ChangeRecord changeRecord = new ChangeRecord();
        changeRecord.setAmount(amount);
        changeRecord.setMainAccountId(mainAccountId);
        changeRecord.setTags(tags);
        changeRecord.setSubject(subject);
        changeRecord.setTrackingId(trackingId);
        changeRecord.setParentMainAccountId(mainAccountMap.get(mainAccountId).getParentMainAccountId());
        changeRecord.setRemark(remark);
        changeRecord.setCreateTime(now);
        changeRecord.setUpdateTime(now);
        changeRecord.setSettleStatus(0);
        changeRecord.setDirection(direction);

        ChangeRecord relChangeRecord = new ChangeRecord();
        relChangeRecord.setAmount(relAmount);
        relChangeRecord.setMainAccountId(relMainAccountId);
        relChangeRecord.setTags(tags);
        relChangeRecord.setSubject(relSubject);
        relChangeRecord.setTrackingId(trackingId);
        relChangeRecord.setParentMainAccountId(mainAccountMap.get(mainAccountId).getParentMainAccountId());
        relChangeRecord.setRemark(relRemark);
        relChangeRecord.setCreateTime(now);
        relChangeRecord.setUpdateTime(now);
        relChangeRecord.setSettleStatus(0);
        changeRecord.setDirection(relDirection);
        changeRecordService.insertBatch(Arrays.asList(changeRecord,relChangeRecord ));

        return Arrays.asList(changeRecord,relChangeRecord);


    }

    @Override
    public void decreaseBalance(Long mainAccountId, BigDecimal amount) {
        MainAccount mainAccount = mainAccountService.findById(mainAccountId);
        if(mainAccount.getBalanceAmount().compareTo(amount) < 0){
            throw new BusException("账户余额不足");
        }
        MainAccount update = new MainAccount();
        update.setBalanceAmount(mainAccount.getBalanceAmount().subtract(amount));
        Example<MainAccount> example = MainAccount.createExample();
        example.createCriteria().andEqualTo("mainAccountId",mainAccount.getMainAccountId())
                .andEqualTo("balanceAmount" ,mainAccount.getBalanceAmount());
        mainAccountService.updateSelectiveByExample(update,example);

    }

    @Override
    public void increaseBalance(Long mainAccountId, BigDecimal amount) {
        MainAccount mainAccount = mainAccountService.findById(mainAccountId);

        MainAccount update = new MainAccount();
        update.setBalanceAmount(mainAccount.getBalanceAmount().add(amount));
        Example<MainAccount> example = MainAccount.createExample();
        example.createCriteria().andEqualTo("mainAccountId",mainAccount.getMainAccountId())
                .andEqualTo("balanceAmount" ,mainAccount.getBalanceAmount());
        mainAccountService.updateSelectiveByExample(update,example);

    }

    @Override
    public List<ChangeRecord> findChangeRecordsByTrackingId(Long trackingId, String subject, Integer direction ) {
        Example<ChangeRecord> example = ChangeRecord.createExample();
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("trackingId" , trackingId ).andEqualTo("subject" , subject).andEqualTo("direction" ,direction );
        return changeRecordService.findListByExample(example);
    }

    @Override
    public void bookConsumeCourse(Long mainAccountId, BigDecimal amount, String className, Long classId, Long regId) {
        book(mainAccountId, amount , 1 , "【" + className + "】收入", Subjects.FUTURE_INCOME, mainAccountId, amount, 0, "【" + className + "】营收", Subjects.REAL_INCOME, regId, "class:" + classId);
    }

    @Override
    public void bookTeacherCost(Long mainAccountId, Long relMainAccountId, BigDecimal amount, String className, String lectureNo, Long classId, Long finishLectureId) {
        book(mainAccountId, amount,0, "【" + className + "】【第"+lectureNo+"讲】薪酬", Subjects.COST, mainAccountId, amount , 0 , "【" + className + "】【第"+lectureNo+"讲】薪酬" , Subjects.REAL_INCOME, finishLectureId, "class:" + classId);
    }
}
